package com.gitee.hljdrl.database;

import android.content.ContentValues;
import android.provider.BaseColumns;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;

import java.util.HashMap;
import java.util.Map;


/**
 * KV数据表，多用户存储 key做区别
 * 例如保存单个用户设置: key=uid+"_setting_xxx" , value="业务value"
 */
public class KVTable extends AbstractTable {

    public static final class Fields implements BaseColumns {

        public static final String TAB_NAME = "_KVTable";
        //
        public static final String DATA_KEY = "_DATA_KEY";
        public static final String DATA_BODY = "_DATA_BODY";
        public static final String DATA_TIME = "_DATA_TIME";

        public static final String COLUMNS[] = {_ID, DATA_KEY, DATA_BODY, DATA_TIME};
    }

    private static KVTable instance;

    public static KVTable getInstance() {
        if (instance == null) {
            instance = new KVTable();
        }
        return instance;
    }

    private KVTable() {

    }

    @Override
    protected String getTableName() {
        return Fields.TAB_NAME;
    }

    @Override
    protected String[] getProjection() {
        return Fields.COLUMNS;
    }

    @Override
    public void create(SQLiteDatabase db) {
        String sql;
        sql = "CREATE TABLE " + Fields.TAB_NAME + " ("
                + Fields._ID + " INTEGER PRIMARY KEY,"
                + Fields.DATA_KEY + " TEXT,"
                + Fields.DATA_TIME + " INTEGER,"
                + Fields.DATA_BODY + " TEXT);";
        DataBaseManager.execSQL(db, sql);

    }

    public int saveItem(String key, String body) {
        ContentValues cv = new ContentValues();
        cv.put(Fields.DATA_KEY, key);
        cv.put(Fields.DATA_BODY, body);
        cv.put(Fields.DATA_TIME, System.currentTimeMillis());

        SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
        int $id = hasItem(key);
        if ($id > -1) {
            int $rid = db.update(getTableName(), cv, Fields._ID + "=?", new String[]{String.valueOf($id)});
            return $rid;
        } else {
            long id = db.insert(getTableName(), null, cv);
            return (int) id;
        }
    }


    public int deleteItem(String key) {
        try {
            SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
            int _id = db.delete(getTableName(), Fields.DATA_KEY + "=?", new String[]{key});
            return _id;
        } catch (Exception ex) {
        }
        return 0;
    }

    public int deleteLikeItem(String key) {
        try {
            SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
            int _id = db.delete(getTableName(), Fields.DATA_KEY + " LIKE ? ",
                    new String[]{string("%", key, "%")});
            return _id;
        } catch (Exception ex) {
        }
        return 0;
    }


    public int hasItem(String key) {
        SQLiteDatabase db = DataBaseManager.getInstance().getReadableDatabase();
        Cursor c = db.query(getTableName(), getProjection(), Fields.DATA_KEY + "=?", new String[]{key}, null, null, null);
        if (hasData(c)) {
            c.moveToFirst();
            int _id = c.getInt(c.getColumnIndex(Fields._ID));
            closeCursor(c);
            return _id;
        } else {
            closeCursor(c);
            return -1;
        }
    }

    public boolean hasKeyValue(String key) {
        SQLiteDatabase db = DataBaseManager.getInstance().getReadableDatabase();
        Cursor c = db.query(getTableName(), getProjection(), Fields.DATA_KEY + "=?", new String[]{key}, null, null, null);
        if (hasData(c)) {
            c.moveToFirst();
//			int _id = c.getInt(c.getColumnIndex(Fields._ID));
            closeCursor(c);
            return Boolean.TRUE;
        } else {
            closeCursor(c);
            return Boolean.FALSE;
        }
    }

    public Map<String, String> readMap() {
        Map<String, String> mRm = new HashMap<String, String>();
        Cursor c = list();
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            String $key = getStringValue(c, Fields.DATA_KEY);
            String $body = getStringValue(c, Fields.DATA_BODY);
            mRm.put($key, $body);
        }
        closeCursor(c);
        return mRm;
    }

    public String readItem(String _key, String _default) {
        String _result = _default;
        Cursor c = list(Fields.DATA_KEY + "=?", new String[]{_key});
        try {
            if (c != null && c.getCount() > 0) {
                c.moveToFirst();
                String $body = getStringValue(c, Fields.DATA_BODY);
                _result = $body;
            }
        } finally {
            closeCursor(c);
        }
        return _result;
    }

    public int readItemInt(String _key, int defaultValue) {
        int _result = defaultValue;
        Cursor c = list(Fields.DATA_KEY + "=?", new String[]{_key});
        try {
            if (c != null && c.getCount() > 0) {
                c.moveToFirst();
                String $body = getStringValue(c, Fields.DATA_BODY);
                try {
                    _result = Integer.parseInt($body);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } finally {
            closeCursor(c);
        }
        return _result;
    }

    protected String readItem(String name) {
        String _result = null;
        Cursor c = list(KVTable.Fields.DATA_KEY + "=?", new String[]{name});
        try {
            if (c != null && c.getCount() > 0) {
                c.moveToFirst();
                String readValue = getStringValue(c, KVTable.Fields.DATA_BODY);
                _result = readValue;
            }
        } finally {
            closeCursor(c);
        }
        return _result;
    }

    public String readItemAsString(String name, String _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        return result;
    }

    public int readItemAsInt(String name, int _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        try {
            return Integer.parseInt(result);
        } catch (Exception ex) {
            //TODO
        }
        return _default;
    }

    public long readItemAsLong(String name, long _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        try {
            return Long.parseLong(result);
        } catch (Exception ex) {
            //TODO
        }
        return _default;
    }

    public float readItemAsFloat(String name, float _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        try {
            return Float.parseFloat(result);
        } catch (Exception ex) {
            //TODO
        }
        return _default;
    }

    public double readItemAsDouble(String name, double _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        try {
            return Double.parseDouble(result);
        } catch (Exception ex) {
            //TODO
        }
        return _default;
    }

    public boolean readItemAsBoolean(String name, boolean _default) {
        String result = readItem(name);
        if (result == null) {
            return _default;
        }
        try {
            return Boolean.parseBoolean(result);
        } catch (Exception ex) {
            //TODO
        }
        return _default;
    }
}
